//+------------------------------------------------------------------+
//|                  DXDispatcher.mqh DirectX 资源调度器头文件       |
//|                版权所有 2000-2025, MetaQuotes Ltd.              |
//|                        官方网址: https://www.mql5.com            |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."  // 版权声明
#property link      "https://www.mql5.com"                 // 官方链接

#include "DXObjectBase.h"  // 引入 DirectX 对象基类（提供资源引用计数与链表管理）
#include "DXData.h"        // 引入 DirectX 数据结构（顶点、常量缓冲区格式等）
#include "DXBuffers.h"     // 引入 DirectX 缓冲类（顶点/索引缓冲区管理）
#include "DXInput.h"       // 引入 DirectX 输入缓冲类（着色器常量缓冲区）
#include "DXTexture.h"     // 引入 DirectX 纹理类（纹理资源管理）
#include "DXShader.h"      // 引入 DirectX 着色器类（顶点/像素着色器管理）

// 内置默认着色器资源（HLSL 源码，编译后用于基础渲染）
#resource "Shaders/DefaultShaderVertex.hlsl" as string ExtDefaultShaderVertex;  // 默认顶点着色器源码
#resource "Shaders/DefaultShaderPixel.hlsl"  as string ExtDefaultShaderPixel;   // 默认像素着色器源码

//+------------------------------------------------------------------+
//| CDXDispatcher 类                                                 |
//| 功能：MT5 DirectX 3D 资源调度核心类，统一管理渲染所需全部资源    |
//| 继承关系：public CDXObjectBase（基于对象基类，支持引用计数与链表）|
//| 核心特性：                                                      |
//|  1. 集中管理 DirectX 资源（着色器、缓冲、纹理、输入缓冲等）      |
//|  2. 提供资源创建标准化接口（模板化支持任意顶点/输入格式）        |
//|  3. 自动维护资源生命周期（引用计数+统一销毁，避免内存泄漏）      |
//|  4. 内置默认着色器（无需外部文件即可实现基础光照渲染）           |
//|  5. 绑定 DirectX 上下文，确保所有资源在同一渲染环境中使用        |
//+------------------------------------------------------------------+
class CDXDispatcher : public CDXObjectBase
  {
protected:
   CDXObjectBase     m_dx_resources;         // DirectX 资源链表（管理所有创建的资源：纹理、着色器、缓冲等）
   CDXShader*        m_default_vs;           // 默认顶点着色器（内置，用于基础渲染，避免重复创建）
   CDXShader*        m_default_ps;           // 默认像素着色器（内置，支持基础光照与颜色渲染）

public:
   /**
    * @brief 构造函数：初始化 DirectX 资源调度器
    * @details 调用父类 CDXObjectBase 构造函数，初始化资源链表与默认着色器指针（初始为 NULL）
    */
                     CDXDispatcher(void);

   /**
    * @brief 析构函数：销毁资源调度器
    * @details 自动调用 Destroy 方法，统一释放所有资源（默认着色器+资源链表），避免内存泄漏
    */
                    ~CDXDispatcher(void);

   //--- 调度器初始化与销毁接口
   /**
    * @brief 初始化调度器（绑定 DirectX 上下文）
    * @param context [in] DirectX 上下文句柄（由 DXCreateContext 创建，标识渲染环境）
    * @return bool - 操作结果：true 表示初始化成功（上下文绑定完成），false 表示失败（如上下文已绑定）
    * @note 必须在创建其他资源前调用，所有后续创建的资源均关联此上下文
    */
   bool              Create(int context);

   /**
    * @brief 销毁调度器（释放所有资源）
    * @details 流程：1. 释放默认着色器（m_default_vs/m_default_ps）；2. 遍历资源链表释放所有资源；3. 清空上下文句柄
    * @note 调用后调度器不可再使用，需重新 Create 初始化
    */
   void              Destroy(void);

   /**
    * @brief 检查并清理无效资源（根据引用计数自动释放无人使用的资源）
    * @details 遍历资源链表，释放引用计数 ≤1 的资源（仅调度器持有引用时），适用于动态资源管理场景
    */
   void              Check(void);

   /**
    * @brief 获取绑定的 DirectX 上下文句柄
    * @return int - DirectX 上下文句柄（INVALID_HANDLE 表示未初始化）
    * @note 用于验证调度器是否已初始化，或传递给其他需要上下文的接口
    */
   int               DXContext(void) const { return(m_context); }

   //--- 着色器创建接口（支持默认/文件/源码三种方式）
   /**
    * @brief 创建内置默认着色器（无需外部文件，快速实现基础渲染）
    * @param shader_type [in] 着色器类型（ENUM_DX_SHADER_TYPE：DX_SHADER_VERTEX 顶点着色器 / DX_SHADER_PIXEL 像素着色器）
    * @return CDXShader* - 着色器对象指针：成功返回有效指针，失败返回 NULL（如类型不支持）
    * @note 顶点着色器自动绑定 DXVertex 布局（支持位置/法向量/纹理坐标/颜色），像素着色器支持基础光照
    */
   CDXShader*        ShaderCreateDefault(ENUM_DX_SHADER_TYPE shader_type);

   /**
    * @brief 从 HLSL 文件创建着色器
    * @param shader_type [in] 着色器类型（顶点/像素着色器）
    * @param path [in] HLSL 源码文件路径（绝对路径或相对于 MQL5 目录的相对路径）
    * @param entry_point [in] 着色器入口函数名（HLSL 中定义的主函数，如 "VSMain" 顶点着色器入口）
    * @return CDXShader* - 着色器对象指针：成功返回有效指针，失败返回 NULL（文件不存在/编译错误）
    * @note 支持最大 16MB 源码文件，自动读取并编译 HLSL 代码
    */
   CDXShader*        ShaderCreateFromFile(ENUM_DX_SHADER_TYPE shader_type,string path,string entry_point);

   /**
    * @brief 从 HLSL 源码字符串创建着色器（适用于动态生成着色器）
    * @param shader_type [in] 着色器类型（顶点/像素着色器）
    * @param source [in] HLSL 源码字符串（完整的着色器代码，包含入口函数）
    * @param entry_point [in] 着色器入口函数名（需与源码中定义一致）
    * @return CDXShader* - 着色器对象指针：成功返回有效指针，失败返回 NULL（源码错误/上下文未初始化）
    * @note 创建后自动添加到资源链表，由调度器管理生命周期
    */
   CDXShader*        ShaderCreateFromSource(ENUM_DX_SHADER_TYPE shader_type,string source,string entry_point);

   //--- 缓冲创建接口（模板化支持任意顶点格式）
   /**
    * @brief 创建顶点缓冲区（模板方法，支持任意顶点数据格式）
    * @tparam TVertex 顶点数据类型（需符合 DirectX 顶点布局规范，如 DXVertex 或自定义结构体）
    * @param vertices [in] 顶点数据数组（存储待上传至 GPU 的顶点数据）
    * @param start [in] 数组起始索引（从该位置开始读取顶点数据，默认 0）
    * @param count [in] 顶点数量（需上传的顶点总数，默认 WHOLE_ARRAY 表示使用整个数组）
    * @return CDXVertexBuffer* - 顶点缓冲区指针：成功返回有效指针，失败返回 NULL（上下文未初始化/内存不足）
    * @note 创建后自动添加到资源链表，由调度器管理生命周期
    */
   template<typename TVertex>
   CDXVertexBuffer*  VertexBufferCreate(const TVertex &vertices[],uint start=0,uint count=WHOLE_ARRAY);

   /**
    * @brief 创建索引缓冲区（用于复用顶点数据，减少 GPU 内存占用）
    * @param indicies [in] 索引数据数组（uint 类型，存储顶点索引，值需在顶点数组有效范围内）
    * @param start [in] 数组起始索引（从该位置开始读取索引数据，默认 0）
    * @param count [in] 索引数量（需上传的索引总数，默认 WHOLE_ARRAY 表示使用整个数组）
    * @return CDXIndexBuffer* - 索引缓冲区指针：成功返回有效指针，失败返回 NULL（上下文未初始化/内存不足）
    * @note 索引值需满足 0 ≤ 索引 < 顶点总数，否则渲染会出现异常
    */
   CDXIndexBuffer*   IndexBufferCreate(const uint &indicies[],uint start=0,uint count=WHOLE_ARRAY);

   //--- 着色器输入缓冲创建接口（常量缓冲区，传递渲染参数）
   /**
    * @brief 创建着色器输入缓冲（模板方法，支持任意常量缓冲区格式）
    * @tparam TInput 输入数据类型（需符合着色器常量缓冲区布局，如 DXInputScene/DXInputObject 或自定义结构体）
    * @return CDXInput* - 输入缓冲指针：成功返回有效指针，失败返回 NULL（上下文未初始化/内存不足）
    * @note 用于传递渲染参数（如视图矩阵、材质颜色）给着色器，需与着色器中的 cbuffer 格式严格对应
    */
   template<typename TInput>
   CDXInput*         InputCreate(void);

   //--- 纹理创建接口（支持文件与原始数据）
   /**
    * @brief 从图片文件创建纹理（支持常见格式：BMP、PNG、JPG 等）
    * @param path [in] 图片文件路径（绝对路径或相对于 MQL5/Images 目录的相对路径）
    * @param data_x [in] 纹理数据起始 X 坐标（默认 0，用于截取图片部分区域作为纹理）
    * @param data_y [in] 纹理数据起始 Y 坐标（默认 0）
    * @param data_width [in] 纹理宽度（默认 0，表示使用图片原始宽度）
    * @param data_height [in] 纹理高度（默认 0，表示使用图片原始高度）
    * @return CDXTexture* - 纹理对象指针：成功返回有效指针，失败返回 NULL（文件不存在/格式不支持）
    * @note 自动解析图片格式，上传至 GPU 作为纹理资源，支持 mipmap 生成（提升缩放渲染质量）
    */
   CDXTexture*       TextureCreateFromFile(string path,uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0);

   /**
    * @brief 从原始数据创建纹理（适用于动态生成纹理，如实时绘制结果）
    * @param format [in] 纹理像素格式（ENUM_DX_FORMAT，需为 32 位格式，如 DX_FORMAT_R8G8B8A8_UNORM）
    * @param width [in] 纹理宽度（像素，必须 >0，建议为 2 的幂次以优化 GPU 性能）
    * @param height [in] 纹理高度（像素，必须 >0，建议为 2 的幂次）
    * @param data [in] 像素数据数组（uint 类型，每个元素对应一个像素，格式需与 format 匹配）
    * @param data_x [in] 数据起始 X 坐标（默认 0，用于填充纹理部分区域）
    * @param data_y [in] 数据起始 Y 坐标（默认 0）
    * @param data_width [in] 数据宽度（默认 0，表示使用纹理宽度）
    * @param data_height [in] 数据高度（默认 0，表示使用纹理高度）
    * @return CDXTexture* - 纹理对象指针：成功返回有效指针，失败返回 NULL（格式不支持/数据长度不足）
    * @note 仅支持 32 位像素格式，数据数组长度需 ≥ data_width * data_height
    */
   CDXTexture*       TextureCreateFromData(ENUM_DX_FORMAT format,uint width,uint height,const uint &data[],uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0);

private:
   /**
    * @brief 添加资源到调度器管理链表（内部辅助方法）
    * @param resource [in] 待添加的资源对象（需继承 CDXObjectBase，支持链表管理）
    * @return bool - 操作结果：true 表示添加成功（资源已加入链表），false 表示失败（资源无效/已存在）
    * @note 所有通过调度器创建的资源都会自动调用此方法，确保统一管理
    */
   bool              ResourceAdd(CDXObjectBase *resource);

   /**
    * @brief 检查资源链表（内部辅助方法，由 Check 调用）
    * @details 遍历资源链表，处理引用计数与资源有效性，具体逻辑由 Check 方法封装
    */
   void              ResourcesCheck(void);
  };
//+------------------------------------------------------------------+